﻿// License Rider: I really don't care how you use this code, or if you give credit. Just don't blame me for any damage you do
using System;
using System.Runtime.InteropServices;

namespace ProdSpy.Core
{
    internal static class NativeMethods
    {

        /// <summary>
        ///  Native version of managed Point
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        internal struct POINT
        {
            /// <summary>
            ///
            /// </summary>
            /// <remarks></remarks>
            public int X;

            /// <summary>
            ///
            /// </summary>
            /// <remarks></remarks>
            public int Y;

            /// <summary>
            /// Initializes a new instance of the <see cref="POINT" /> struct.
            /// </summary>
            /// <param name="x">The x.</param>
            /// <param name="y">The y.</param>
            /// <remarks></remarks>
            public POINT(int x, int y)
            {
                X = x;
                Y = y;
            }

            /// <summary>
            /// Implements the operator ==.
            /// </summary>
            /// <param name="p1">The p1.</param>
            /// <param name="p2">The p2.</param>
            /// <returns>The result of the operator.</returns>
            /// <remarks></remarks>
            public static bool operator ==(POINT p1, POINT p2)
            {
                return p1.X == p2.X && p1.Y == p2.Y;
            }

            /// <summary>
            /// Implements the operator !=.
            /// </summary>
            /// <param name="p1">The p1.</param>
            /// <param name="p2">The p2.</param>
            /// <returns>The result of the operator.</returns>
            /// <remarks></remarks>
            public static bool operator !=(POINT p1, POINT p2)
            {
                return p1.X != p2.X || p1.Y != p2.Y;
            }

            /// <summary>
            /// Equalses the specified other.
            /// </summary>
            /// <param name="other">The other.</param>
            /// <returns></returns>
            /// <remarks></remarks>
            public bool Equals(POINT other)
            {
                return other.X == X && other.Y == Y;
            }

            /// <summary>
            /// Equalses the specified obj.
            /// </summary>
            /// <param name="obj">The obj.</param>
            /// <returns></returns>
            /// <remarks></remarks>
            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj))
                {
                    return false;
                }

                if (obj.GetType() != typeof(POINT))
                {
                    return false;
                }

                return Equals((POINT)obj);
            }

            /// <summary>
            /// Gets the hash code.
            /// </summary>
            /// <returns></returns>
            /// <remarks></remarks>
            public override int GetHashCode()
            {
                unchecked
                {
                    return (X * 397) ^ Y;
                }
            }
        }

        /// <summary>
        /// Destroys an icon and frees any memory the icon occupied
        /// </summary>
        /// <param name="handle">A handle to the icon to be destroyed. The icon must not be in use</param>
        /// <returns>If the function succeeds, the return value is nonzero</returns>
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DestroyIcon(IntPtr handle);

        /// <summary>
        /// Retrieves the cursor's position, in screen coordinates
        /// </summary>
        /// <param name="lpPoint">A pointer to a POINT structure that receives the screen coordinates of the cursor</param>
        /// <returns>Returns nonzero if successful or zero otherwise</returns>
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetCursorPos(out POINT lpPoint);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, [MarshalAs(UnmanagedType.Bool)] bool bErase);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool UpdateWindow(IntPtr hWnd);
    }
}